import pytest
import allure
from playwright.sync_api import Page, expect
import os

@allure.feature("文件管理")
@allure.story("文件上传功能")
class TestUpload:
    
    @pytest.fixture
    def login(self, page: Page):
        """登录fixture"""
        with allure.step("执行登录"):
            page.goto("http://localhost:8080")
            page.locator('input[placeholder="请输入用户名"]').fill("testuser")
            page.locator('input[placeholder="请输入密码"]').fill("password123")
            page.get_by_role("button", name="登录").click()
            page.wait_for_url("**/testplanform/home")
        return page
    
    @allure.title("测试API文件上传页面的基本元素")
    @allure.severity(allure.severity_level.NORMAL)
    def test_api_file_upload_page_elements(self, page: Page, login):
        """测试API文件上传页面的基本元素"""
        with allure.step("导航到API文件上传页面"):
            page.goto("http://localhost:8080/upload/api")
        
        with allure.step("检查页面标题"):
            expect(page.get_by_text("API文件上传")).to_be_visible()
        
        with allure.step("检查上传区域"):
            expect(page.locator('.el-upload-dragger')).to_be_visible()
            expect(page.get_by_text("将文件拖到此处，或点击上传")).to_be_visible()
        
        with allure.step("检查文件列表区域"):
            expect(page.locator('.el-table')).to_be_visible()

    @allure.title("测试需求文件上传页面的基本元素")
    @allure.severity(allure.severity_level.NORMAL)
    def test_need_file_upload_page_elements(self, page: Page, login):
        """测试需求文件上传页面的基本元素"""
        with allure.step("导航到需求文件上传页面"):
            page.goto("http://localhost:8080/upload/need")
        
        with allure.step("检查页面标题"):
            expect(page.get_by_text("需求文件上传")).to_be_visible()
        
        with allure.step("检查上传区域"):
            expect(page.locator('.el-upload-dragger')).to_be_visible()
            expect(page.get_by_text("将文件拖到此处，或点击上传")).to_be_visible()
        
        with allure.step("检查文件列表区域"):
            expect(page.locator('.el-table')).to_be_visible()

    @allure.title("测试API文件上传成功场景")
    @allure.severity(allure.severity_level.CRITICAL)
    def test_api_file_upload_success(self, page: Page, login):
        """测试API文件上传成功场景"""
        with allure.step("导航到API文件上传页面"):
            page.goto("http://localhost:8080/upload/api")
        
        with allure.step("创建测试文件"):
            test_file_path = "test_api.xlsx"
            with open(test_file_path, "w") as f:
                f.write("Test API File Content")
            
            allure.attach.file(test_file_path, name="测试API文件", attachment_type=allure.attachment_type.TEXT)
        
        with allure.step("上传文件"):
            page.locator('input[type="file"]').set_input_files(test_file_path)
        
        with allure.step("验证上传成功提示"):
            success_message = page.locator('.el-message--success')
            expect(success_message).to_be_visible()
            expect(success_message).to_contain_text("上传成功")
        
        with allure.step("验证文件列表中显示新文件"):
            expect(page.get_by_text("test_api.xlsx")).to_be_visible()
        
        with allure.step("清理测试文件"):
            os.remove(test_file_path)

    @allure.title("测试需求文件上传成功场景")
    @allure.severity(allure.severity_level.CRITICAL)
    def test_need_file_upload_success(self, page: Page, login):
        """测试需求文件上传成功场景"""
        with allure.step("导航到需求文件上传页面"):
            page.goto("http://localhost:8080/upload/need")
        
        with allure.step("创建测试文件"):
            test_file_path = "test_need.docx"
            with open(test_file_path, "w") as f:
                f.write("Test Need File Content")
            
            allure.attach.file(test_file_path, name="测试需求文件", attachment_type=allure.attachment_type.TEXT)
        
        with allure.step("上传文件"):
            page.locator('input[type="file"]').set_input_files(test_file_path)
        
        with allure.step("验证上传成功提示"):
            success_message = page.locator('.el-message--success')
            expect(success_message).to_be_visible()
            expect(success_message).to_contain_text("上传成功")
        
        with allure.step("验证文件列表中显示新文件"):
            expect(page.get_by_text("test_need.docx")).to_be_visible()
        
        with allure.step("清理测试文件"):
            os.remove(test_file_path)

    @allure.title("测试上传无效文件类型")
    @allure.severity(allure.severity_level.NORMAL)
    def test_invalid_file_type(self, page: Page, login):
        """测试上传无效文件类型"""
        with allure.step("导航到API文件上传页面"):
            page.goto("http://localhost:8080/upload/api")
        
        with allure.step("创建无效类型的测试文件"):
            test_file_path = "test.txt"
            with open(test_file_path, "w") as f:
                f.write("Invalid file type")
            
            allure.attach.file(test_file_path, name="无效类型文件", attachment_type=allure.attachment_type.TEXT)
        
        with allure.step("上传文件"):
            page.locator('input[type="file"]').set_input_files(test_file_path)
        
        with allure.step("验证错误提示"):
            error_message = page.locator('.el-message--error')
            expect(error_message).to_be_visible()
            expect(error_message).to_contain_text("不支持的文件类型")
        
        with allure.step("清理测试文件"):
            os.remove(test_file_path)

    @allure.title("测试文件大小限制")
    @allure.severity(allure.severity_level.NORMAL)
    def test_file_size_limit(self, page: Page, login):
        """测试文件大小限制"""
        with allure.step("导航到API文件上传页面"):
            page.goto("http://localhost:8080/upload/api")
        
        with allure.step("创建大文件"):
            test_file_path = "large_file.xlsx"
            with open(test_file_path, "wb") as f:
                f.write(b"0" * (10 * 1024 * 1024))  # 10MB文件
            
            allure.attach(
                "已创建10MB大小的测试文件",
                name="大文件信息",
                attachment_type=allure.attachment_type.TEXT
            )
        
        with allure.step("上传文件"):
            page.locator('input[type="file"]').set_input_files(test_file_path)
        
        with allure.step("验证错误提示"):
            error_message = page.locator('.el-message--error')
            expect(error_message).to_be_visible()
            expect(error_message).to_contain_text("文件大小超出限制")
        
        with allure.step("清理测试文件"):
            os.remove(test_file_path)

    @allure.title("测试删除已上传文件")
    @allure.severity(allure.severity_level.NORMAL)
    def test_delete_uploaded_file(self, page: Page, login):
        """测试删除已上传文件"""
        with allure.step("导航到API文件上传页面"):
            page.goto("http://localhost:8080/upload/api")
        
        with allure.step("创建并上传测试文件"):
            test_file_path = "test_delete.xlsx"
            with open(test_file_path, "w") as f:
                f.write("Test Delete File")
            
            page.locator('input[type="file"]').set_input_files(test_file_path)
            page.wait_for_selector(f'text="test_delete.xlsx"')
        
        with allure.step("点击删除按钮"):
            page.get_by_role("button", name="删除").click()
        
        with allure.step("确认删除"):
            page.get_by_role("button", name="确定").click()
        
        with allure.step("验证文件已被删除"):
            expect(page.get_by_text("test_delete.xlsx")).not_to_be_visible()
        
        with allure.step("清理测试文件"):
            os.remove(test_file_path)

    @allure.title("测试批量上传文件")
    @allure.severity(allure.severity_level.NORMAL)
    def test_batch_upload(self, page: Page, login):
        """测试批量上传文件"""
        with allure.step("导航到API文件上传页面"):
            page.goto("http://localhost:8080/upload/api")
        
        with allure.step("创建多个测试文件"):
            test_files = ["test1.xlsx", "test2.xlsx", "test3.xlsx"]
            for file_name in test_files:
                with open(file_name, "w") as f:
                    f.write(f"Content of {file_name}")
                
                allure.attach.file(file_name, name=f"批量测试文件: {file_name}", attachment_type=allure.attachment_type.TEXT)
        
        with allure.step("批量上传文件"):
            page.locator('input[type="file"]').set_input_files(test_files)
        
        with allure.step("验证所有文件都上传成功"):
            for file_name in test_files:
                expect(page.get_by_text(file_name)).to_be_visible()
        
        with allure.step("清理测试文件"):
            for file_name in test_files:
                os.remove(file_name) 